package weapon

import (
	"fmt"
	"strings"
	"path/filepath"
	"os"
	"io"
	"github.com/astaxie/beego/logs"
	"cloud_worm/wormweb/controllers/ctrutil"
	"cloud_worm/util/ufile"
	"cloud_worm/wormweb/controllers/ctrconfig"
	"cloud_worm/util/uhttp"
)

/**
 weapon 文件上传
 */
type WpUploadController struct {
	ctrconfig.LoginCtr
}

// https://{domain}:{port}/weapon/upload （multipart/form-data;格式）
// 参数:file=文件名&md5=文件md5
func (w *WpUploadController) Post() {
	w.Manager()

	fp, handle, err := w.Ctx.Request.FormFile("file")
	if err != nil {
		logs.Error("read form file error")
		w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "read formfile error!!", nil)
		w.ServeJSON()
		return
	}
	defer fp.Close()
	
	// 防止跨目录 瞎搞
	if strings.Contains(handle.Filename, "..") {
		logs.Error("file contains illegality")
		w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "file contains illegality", nil)
		w.ServeJSON()
		return
	}
	
	ClientMd5 := w.GetString("md5")
	if ClientMd5 == "" {
		logs.Error("read md5 error!!")
		w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeParamErr, "read md5 error!!", nil)
		w.ServeJSON()
		return
	}
	
	// 先写入文件，再md5
	_, fileName := filepath.Split(handle.Filename)
	destFileName := filepath.Join(ctrutil.TmpDir, ctrutil.TmpWeaponsDir, fileName)
	
	newFp, err := os.OpenFile(destFileName, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		logs.Error(fmt.Sprintf("open file '%s' error: %s", destFileName, err.Error()))
		w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr,
			fmt.Sprintf("open file '%s' error: %s", destFileName, err.Error()), nil)
		w.ServeJSON()
		return
	}
	defer newFp.Close()
	defer os.Remove(destFileName)               // 流程结束前，删除文件
	
	// 拷贝文件内容
	_, err = io.Copy(newFp, fp)
	if err != nil {
		logs.Error(fmt.Sprintf("copy file error: %s", err.Error()))
		w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr,
			fmt.Sprintf("copy file '%s' error: %s", destFileName, err.Error()), nil)
		w.ServeJSON()
		return
	}
	
	// 计算改文件的md5,并比较是否一样
	fileMd5 := ufile.GetFileMd5(destFileName)
	if fileMd5 != strings.ToLower(ClientMd5) {
		logs.Error("md5 not same,upload fail")
		w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, "md5 not same,upload fail", nil)
		w.ServeJSON()
		return
	}

	downloadURL, err := ctrutil.ResourceSet().UploadFile(destFileName, ctrutil.UploadWeaponURL)
	if err != nil {
		logs.Error(err.Error())
		w.Data["json"] = uhttp.CreateErrResponse(uhttp.RespCodeSystemErr, err.Error(), nil)
		w.ServeJSON()
		return
	}

	w.Data["json"] = uhttp.CreateOkResponse(map[string]interface{}{"url": downloadURL})
	w.ServeJSON()
	return
}
